﻿#region Usings

using System;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using Castle.MonoRail.Framework;
using Rodunu.Movies.Contracts;
using Rodunu.Movies.Interfaces.Movie;
using Rodunu.Movies.Interfaces.Security;
using Rodunu.Movies.Interfaces.User;
using Rodunu.Movies.Logic.Movie;
using Rodunu.Movies.Logic.User;
using Rodunu.Movies.Logic.Validation;
using Rodunu.Movies.Security;
using Rodunu.Movies.Web.Properties;
using Rodunu.Movies.Web.Security;
using Rodunu.Utilities.Email;
using System.Security;

#endregion

namespace Rodunu.Movies.Web.Controllers
{
    public class AuthenticationController : GuestBaseController
    {
        #region Private Members

        private readonly IUserAuthentication _userAuthentication;
        private readonly WebAuthentication _webAuthentication;
        private readonly IUser _userLogic;
        private readonly IUserValidation _validationLogic;
        private string _checkCode;
        private readonly IShareMovies _shareMoviesLogic;

        #endregion

        #region Controllers

        public AuthenticationController()
        {
            _userAuthentication = new UserAuthentication();
            _webAuthentication = new WebAuthentication();
            _userLogic = new UserLogic();
            _shareMoviesLogic = new ShareMoviesLogic();
            _validationLogic = new ValidationLogic();
        }

        #endregion

        public void Index(string status)
        {
            PropertyBag["shareMovies"] = _shareMoviesLogic.FindAll();

            PropertyBag["AccountHasError"] = false;
            if (string.IsNullOrEmpty(status)) return;

            PropertyBag["AccountHasError"] = true;
            PropertyBag["AccountError"] = status.ToUpper();

        }

        public void Login([DataBind("user")] UserInfo user, bool rememberMe, string returnUrl)
        {
            try
            {
                user = _userAuthentication.Authenticate(user.UserName, user.Password,
                                                        System.Web.HttpContext.Current.Request.UserHostAddress);
                switch (user.Status)
                {
                    case UserStatusTypes.Status.Active:
                        user.IsLoggedIn = true;
                        User = user;
                        _webAuthentication.SetAuthCookie(user, rememberMe, GetCookiePath(), Response);

                        if (!String.IsNullOrEmpty(returnUrl))
                            Redirect(returnUrl);
                        else
                            Redirect("home", "index");
                        break;
                    case UserStatusTypes.Status.Banned:
                        RedirectToAction("Index", "status=" + user.Status);
                        break;
                    case UserStatusTypes.Status.Disabled:
                        RedirectToAction("Index", "status=" + user.Status);
                        break;
                    case UserStatusTypes.Status.Pending:
                        RedirectToAction("Index", "status=" + user.Status);
                        break;
                    default:
                        //_webAuthentication.SetAuthCookie(user, rememberMe, GetCookiePath());
                        Redirect("home", "index");
                        break;
                }
            }
            catch (SecurityException sx)
            {
                Redirect("Authentication", "register");
            }

        }

        #region Logout

        public void Logout()
        {
            _webAuthentication.SignOut(Response, Request);
            User = null;
            Redirect("home", "index");
        }

        #endregion

        #region Signup

        public void Register()
        {
            PropertyBag["shareMovies"] = _shareMoviesLogic.FindAll();
        }

        public void SignUp([DataBind("profile")] UserInfo profile, string password2, string imageVer, bool rememberMe, string returnUrl)
        {
            if (profile.Password.Length > 5)
            {
                if (profile.Password == password2)
                {
                    if (Verification.VerifyEmail(profile.EmailAddress))
                    {
                        if (Session["image.key"] != null)
                        {
                            if (imageVer == Convert.ToString(Session["image.key"]))
                            {
                                if (string.IsNullOrEmpty(profile.FirstName))
                                    profile.FirstName = "";
                                if (string.IsNullOrEmpty(profile.LastName))
                                    profile.LastName = "";

                                profile.DateAdded = DateTime.Now;
                                profile.LastModifiedBy = DateTime.Now;
                                profile.Status = UserStatusTypes.Status.Pending;
                                string pwd = profile.Password;

                                _userLogic.Create(profile);
                                profile.IsLoggedIn = false;

                                string verificationHash = _validationLogic.CreateValidationHash(_userLogic.GetByUserName(profile.UserName, pwd));
                                _webAuthentication.SetAuthCookie(profile, rememberMe, GetCookiePath(), Response);
                                User = profile;

                                //PostOffice mailMan = new PostOffice();
                                //mailMan.SendAccountValidation(profile.EmailAddress, "Account Verify",
                                //                              "http://" + Settings.Default.RootURL +
                                //                              "/Authentication/Validate.ashx?Token=" + verificationHash);
                                Redirect("Home", "Index");
                            }
                            else
                            {
                                RenderText("Image key fail");
                            }
                        }
                        else
                        {
                            RenderText("Image key fail");
                        }
                    }
                    else
                    {
                        RenderText("Email fail");
                    }
                }
                else
                {
                    RenderText("Password fail");
                }
            }
            else
            {
                RenderText("Password fail");
            }
        }

        public void GetImage()
        {
            _checkCode = Verification.CreateRandomCode(6);
            Context.Response.ClearContent();
            Context.Response.ContentType = "image/Gif";
            Context.Response.BinaryWrite(Verification.CreateImage(_checkCode));
            Session["image.key"] = _checkCode;
        }

        #endregion
        
        public string GetCookiePath()
        {
            if (Context == null)
            {
                return "Beta1";
            }
            return "Rodunu";
            //return Context.ApplicationPath + "/";
        }

        public void Validate(string Token)
        {
            UserValidation uv = _validationLogic.Validate(Token);
            IList<UserVerification> uvList = _validationLogic.FindByBase("VerificationToken", HttpUtility.UrlEncode(Token));
            UserInfo user = _userLogic.Find(uv.UserId);
            //RenderText(uvList.Count.ToString());
            //RenderText("Token: " + Token + "<br>Encoded: " + HttpUtility.UrlEncode(Token));

            if (uvList.Count == 1)
            {
                UserVerification userVerification = uvList[0];
                switch (uv.Validity)
                {
                    case UserValidation.TokenValidity.Valid:
                        _userLogic.UpdateUserStatus(uv.UserId, (int)UserStatusTypes.Status.Active);
                        _validationLogic.Delete(userVerification);
                        PostOffice mailMan = new PostOffice();
                        mailMan.SendNewUserWelcomeLetter(user.EmailAddress, "Welcome to Rodunu!", user.FirstName);
                        PropertyBag["ValidationResponse"] = UserValidation.VerificationReturnCode.Success;
                        break;
                    case UserValidation.TokenValidity.Stale:
                        PropertyBag["ValidationResponse"] = UserValidation.VerificationReturnCode.Failed;
                        break;
                    default:
                        PropertyBag["ValidationResponse"] = UserValidation.VerificationReturnCode.Failed;
                        break;
                }
            }
            else
            {
                PropertyBag["ValidationResponse"] = "Failed";
            }
        }
    }
}
